package com.xiaoze.question.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoze.common.utils.DateUtils;
import com.xiaoze.question.domain.QuestionScenario;
import com.xiaoze.question.domain.QuestionScenarioTactics;
import com.xiaoze.question.dto.QuestionAnswerUserInput;
import com.xiaoze.question.dto.QuestionAnswerUsersOutput;
import com.xiaoze.question.dto.QuestionScenarioListOutput;
import com.xiaoze.question.dto.QuestionScenarioTreeOutput;
import com.xiaoze.question.enums.ScenarioTacticsConstants;
import com.xiaoze.question.factory.SceTacFactory;
import com.xiaoze.question.mapper.QuestionScenarioMapper;
import com.xiaoze.question.mapper.QuestionScenarioTacticsMapper;
import com.xiaoze.question.service.IQuestionScenarioService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 业务场景管理Service业务层处理
 *
 * @author 胡昊泽
 * @date 2024-08-02
 */
@Service
public class QuestionScenarioServiceImpl extends ServiceImpl<QuestionScenarioMapper, QuestionScenario> implements IQuestionScenarioService {

    @Autowired
    private QuestionScenarioMapper questionScenarioMapper;

    @Autowired
    private QuestionScenarioTacticsMapper questionScenarioTacticsMapper;

    @Autowired
    private SceTacFactory sceTacFactory;
    /**
     * 查询业务场景管理
     *
     * @param id 业务场景管理ID
     * @return 业务场景管理
     */
    @Override
    public QuestionScenario selectQuestionScenarioById(Long id) {
        return questionScenarioMapper.selectQuestionScenarioById(id);
    }

    /**
    * 方法描述: 查询该问卷下面得所有题目，以及对应得题目选项
    * @Author 胡昊泽 
    * @Date 2024/8/12 16:40
      * @param questionAnswerUserInput: 
    * @return com.xiaoze.question.dto.QuestionAnswerUsersOutput
    */ 
    @Override
    public QuestionAnswerUsersOutput selectQuestionScenarioForUser(QuestionAnswerUserInput questionAnswerUserInput) {
        // 根据问卷调查id查询改策划率
        QuestionScenario questionScenario = questionScenarioMapper.selectById(questionAnswerUserInput.getId());

        return sceTacFactory.getStrategy(ScenarioTacticsConstants.BusTypeEnum.getCode(questionScenario.getTacticsId())).selectBySceTacId(questionAnswerUserInput);
    }

    /**
     * 查询业务场景管理列表
     *
     * @param questionScenario 业务场景管理
     * @return 业务场景管理
     */
    @Override
    public List<QuestionScenarioListOutput> selectQuestionScenarioList(QuestionScenario questionScenario) {
        // 查询出列表信息
        List<QuestionScenario> questionScenarioList = questionScenarioMapper.selectQuestionScenarioList(questionScenario);
        // 取出列表中的策略id
        List<String> tacticsIds = questionScenarioList.stream().map(QuestionScenario::getTacticsId).collect(Collectors.toList());
        // 根据策略id查询 对应的策略类型，然后进行匹配
        List<QuestionScenarioTactics> questionScenarioTactics = questionScenarioTacticsMapper.selectBatchIds(tacticsIds);
        List<QuestionScenarioListOutput> questionScenarioListOutputs = new ArrayList<>();
        // 开始进行数据匹配
        questionScenarioList.stream().map(m -> {
            QuestionScenarioListOutput questionScenarioListOutput = new QuestionScenarioListOutput();
            BeanUtils.copyProperties(m, questionScenarioListOutput);
            // 获取该条数据策略id
            String tacticsId = m.getTacticsId();
            Optional<QuestionScenarioTactics> first = questionScenarioTactics.stream().filter(f -> f.getId() == Long.valueOf(tacticsId)).findFirst();
            questionScenarioListOutput.setTacticsType(first.get().getTacticsType());
            questionScenarioListOutputs.add(questionScenarioListOutput);
            return m;
        }).collect(Collectors.toList());
        return questionScenarioListOutputs;
    }


    /**
     * 新增业务场景管理
     *
     * @param questionScenario 业务场景管理
     * @return 结果
     */
    @Override
    public int insertQuestionScenario(QuestionScenario questionScenario) {
        // 设置创建时间
        questionScenario.setCreateTime(DateUtils.getNowDate());
        // 查询业务场景数量
        Integer categoryCount = questionScenarioMapper.selectCount(new QueryWrapper<>());
        // 设置业务场景编号递增
        questionScenario.setCategory(String.valueOf(categoryCount + 1));
        questionScenario.setUnCode(UUID.randomUUID().toString().replace("-",""));
        return questionScenarioMapper.insertQuestionScenario(questionScenario);
    }

    /**
     * 修改业务场景管理
     *
     * @param questionScenario 业务场景管理
     * @return 结果
     */
    @Override
    public int updateQuestionScenario(QuestionScenario questionScenario) {
        questionScenario.setUpdateTime(DateUtils.getNowDate());
        return questionScenarioMapper.updateQuestionScenario(questionScenario);
    }

    /**
     * 批量删除业务场景管理
     *
     * @param ids 需要删除的业务场景管理ID
     * @return 结果
     */
    @Override
    public int deleteQuestionScenarioByIds(Long[] ids) {
        return questionScenarioMapper.deleteQuestionScenarioByIds(ids);
    }

    /**
     * 删除业务场景管理信息
     *
     * @param id 业务场景管理ID
     * @return 结果
     */
    @Override
    public int deleteQuestionScenarioById(Long id) {
        return questionScenarioMapper.deleteQuestionScenarioById(id);
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param questionScenario 业务场景管理
     * @return 下拉树结构列表
     */
    @Override
    public List<QuestionScenarioTreeOutput> selectQuestionScenarioTreeList(QuestionScenario questionScenario) {
        // 1、查询所有信息
        List<QuestionScenario> questionScenarioList = questionScenarioMapper.selectQuestionScenarioList(questionScenario);
        if (CollectionUtils.isNotEmpty(questionScenarioList)) {
            // 2、将信息转换成为所需要QuestionScenarioTreeOutput结构信息
            List<QuestionScenarioTreeOutput> questionScenarioTreeOutputList = new ArrayList<>(questionScenarioList.size());

            for (QuestionScenario scenario : questionScenarioList) {
                QuestionScenarioTreeOutput questionScenarioTreeOutput = new QuestionScenarioTreeOutput();
                BeanUtils.copyProperties(scenario, questionScenarioTreeOutput);
                questionScenarioTreeOutputList.add(questionScenarioTreeOutput);
            }
            // 3、开始处理结构信息
            //获取父节点
            return questionScenarioTreeOutputList.stream().filter(m -> m.getParentId() == 0).map(
                    (m) -> {
                        m.setChildList(getChildrens(m, questionScenarioTreeOutputList));
                        return m;
                    }
            ).collect(Collectors.toList());

        }

        return null;
    }

    /**
     * 递归查询子节点
     *
     * @param root 根节点
     * @param all  所有节点
     * @return 根节点信息
     */
    private List<QuestionScenarioTreeOutput> getChildrens(QuestionScenarioTreeOutput root, List<QuestionScenarioTreeOutput> all) {
        if(root != null){
            return all.stream().filter(m -> {
                return Objects.equals(m.getParentId(), root.getId());
            }).map(
                    (m) -> {
                        m.setChildList(getChildrens(m, all));
                        return m;
                    }
            ).collect(Collectors.toList());
        }
        return null;
    }
}
